﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Server
{
    public partial class asdfasdf : Form
    {
        
        public asdfasdf()
        {
            InitializeComponent();
        }
        
        private void Form1_Load(object sender, EventArgs e)
        {
            //窗体加载阶段取本机的IP
            var hostName = Dns.GetHostName();

            //当电脑有多个网卡或者是带有虚拟计算器功能时，会有多个IP地址（即IP地址为数组），
            //需要通过名称查询自己的IP
            var localhostIPs = Dns.GetHostByName(hostName);
            IPAddress iP = localhostIPs.AddressList[0];
            txtAddress.Text = iP.ToString();
        }
        #region 监听方法
        private Socket SocketSend;
        private Dictionary<string, Socket> distanceSocket = new Dictionary<string, Socket>();

        private void Listen(object o)
        {

            //网络监听 Socket类局域网通信协议
            Socket SocketWatch = o as Socket;

            while (true)
            {
                //监听
                try
                {
                    //负责和客户通信
                    SocketSend = SocketWatch.Accept();

                    //将远程链接的客户端的IP地址和Socket存入集合中
                    distanceSocket.Add(SocketSend.RemoteEndPoint.ToString(), SocketSend);

                    //将远程连接的客服的IP地址加入下拉框
                    cbxUsers.Items.Add(SocketSend.RemoteEndPoint.ToString());
                    cbxUsers.SelectedText = SocketSend.RemoteEndPoint.ToString();

                    ShowMessage(SocketSend.RemoteEndPoint.ToString() + ":连接成功！");

                    //开新的线程不停的接收客户端发送的信息
                    Thread th = new Thread(Receive);
                    th.IsBackground = true;
                    th.Start(SocketSend);

                }
                catch
                {
                    MessageBox.Show("网络连接错误，请重新输入！");
                }
            }

        }

        #endregion
        /// <summary>
        /// 客户端不停的接受客户端发送的信息
        /// </summary>
        /// <param name="o"></param>
        private void Receive(object o)
        {
            //转换传入的参数类型
            Socket socketSend = o as Socket;

            //用循环持续接收二进制消息，指导消息读取完毕
            while (true)
            {
                // 每2M为一次读取单位
                byte[] buffer = new byte[1024 * 1024 * 2];
                //实际接收的有效字节数
                int r = socketSend.Receive(buffer);
                //指导字节读取完成，跳出循环
                if (r == 0)
                    break;

                //把二进制内容转换为字符串
                var str = Encoding.UTF8.GetString(buffer, 0, r);
                ShowMessage(socketSend.RemoteEndPoint + "：" + str);
            
               //数组的第一个数字表示发送的东西
              //0表示发送文字
                if (buffer[0] == 0)
                {
                    //string str = Encoding.UTF8.GetString(buffer, 1, r - 1);
                }
                else if (buffer[1] == 1)
                {

                }
                else if (buffer[1] == 2)
                {

                }
                else
                {
                    //其他的发送消息类型
                }

            }
        }

        private void ShowMessage(string msgStr)
        {
            //换行，发送给用户提示信息
            txtLog.AppendText(msgStr + "\r\n");
        }

        private void btnMonitor_Click(object sender, EventArgs e)
        {
            try
            {
                //当点击开始监听时，在服务器端创建一个负责监听的IP地址和端口号
                Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Parse(txtAddress.Text);
                //创建端口号对象
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textBox2.Text));


                //开始监听
                socketWatch.Bind(point);
                ShowMessage("监听成功...");
                //参数表示可以同时监听或者接收的用户个数(最大连接个数，同时响应的个数，同时连接的个数，100个一起通信最多处理10个，剩下的排队)
                socketWatch.Listen(10);

                //新建线程持续监听
                Thread th = new Thread(Listen);
                th.IsBackground = true;
                th.Start(socketWatch);

        }
            catch
            {
                MessageBox.Show("网络连接错误，请重新输入！");
            }
}
        //将文本框信息发送到客户端
        private void btnSend_Click(object sender, EventArgs e)
        {
            string str = textBox4.Text;
            //把消息转换为二进制
            byte[] buffer = Encoding.UTF8.GetBytes(str);

            List<byte> list = new List<byte>();
            list.Add(0);
            list.AddRange(buffer);

            //生成新的二进制数组
            byte[] newBuffer = list.ToArray();

            //获得要发送客户端的IP
            string IP = cbxUsers.SelectedItem.ToString();

            if (string.IsNullOrEmpty(IP))
            {
                MessageBox.Show("请先选择客户端!");
                return;
            }

            distanceSocket[IP].Send(newBuffer);
        }

        private void btnVibration_Click(object sender, EventArgs e)
        {
            byte[] buffer = new byte[1];
            buffer[0] = 2;
            distanceSocket[cbxUsers.SelectedItem.ToString()].Send(buffer);
        }

        private void btnSelect_Click(object sender, EventArgs e)
        {
            var dialog = new OpenFileDialog();
            //对话框配置
            dialog.InitialDirectory = @"c:\AAA";//初始目录
            dialog.Title = "请选择要发送的文件";
            dialog.Filter = "所有文件|*.*";
            dialog.ShowDialog(); 

            txtPath.Text = dialog.FileName;


        }

        private void btnfatu_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtPath.Text))
            {
                MessageBox.Show("请选择文件！");
                return;
            }

            var path = txtPath.Text.Trim();
            //请取文件内容，进行发送
            using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read))
            {
                byte[] buffer = new byte[1024 * 1024 * 10];
                int r = fsRead.Read(buffer, 0, buffer.Length);

                //文件数据前加一个类型数据
                List<byte> list = new List<byte>();
                list.Add(1);
                list.AddRange(buffer);
                byte[] newBuffer = list.ToArray();

                //把处理好的二进制数组发送给客户端
                distanceSocket[cbxUsers.SelectedItem.ToString()].Send(newBuffer, 0, r + 1, SocketFlags.None);
            }

        }
    }
}
